﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.Entities.Addresses
{

    [Serializable]
    public class AddressExtractorInstruction:InstructionBase
    {
        #region props
        private DataProviderType _DbProvider;
        /// <summary></summary>
        public DataProviderType DbProvider
        {
            get
            {
                return this._DbProvider;
            }
            set
            {
                this._DbProvider = value;
            }
        }

        private string _ConnStr;
        /// <summary></summary>
        public string ConnStr
        {
            get
            {
                return this._ConnStr;
            }
            set
            {
                this._ConnStr = value;
            }
        }

        private string _SelectSql;
        /// <summary></summary>
        public string SelectSql
        {
            get
            {
                return this._SelectSql;
            }
            set
            {
                this._SelectSql = value;
            }
        }

        private string _PKField;
        /// <summary></summary>
        public string PKField
        {
            get
            {
                return this._PKField;
            }
            set
            {
                this._PKField = value;
            }
        }

        private string _FullAddressField;
        /// <summary></summary>
        public string FullAddressField
        {
            get
            {
                return this._FullAddressField;
            }
            set
            {
                this._FullAddressField = value;
            }
        }

        private DataProviderType _TgtDbProvider;
        /// <summary></summary>
        public DataProviderType TgtDbProvider
        {
            get
            {
                return this._TgtDbProvider;
            }
            set
            {
                this._TgtDbProvider = value;
            }
        }

        private string _TgtConnStr;
        /// <summary></summary>
        public string TgtConnStr
        {
            get
            {
                return this._TgtConnStr;
            }
            set
            {
                this._TgtConnStr = value;
            }
        }

        private string _TgtTable;
        /// <summary></summary>
        public string TgtTable
        {
            get
            {
                return this._TgtTable;
            }
            set
            {
                this._TgtTable = value;
            }
        }

        private string _AddrIDField;
        /// <summary></summary>
        public string AddrIDField
        {
            get
            {
                return this._AddrIDField;
            }
            set
            {
                this._AddrIDField = value;
            }
        }

        private string _RefKeyField;
        /// <summary></summary>
        public string RefKeyField
        {
            get
            {
                return this._RefKeyField;
            }
            set
            {
                this._RefKeyField = value;
            }
        }

        private string _StreetField;
        /// <summary></summary>
        public string StreetField
        {
            get
            {
                return this._StreetField;
            }
            set
            {
                this._StreetField = value;
            }
        }

        private string _SubDivField;
        /// <summary></summary>
        public string SubDivField
        {
            get
            {
                return this._SubDivField;
            }
            set
            {
                this._SubDivField = value;
            }
        }

        private string _OrgField;
        /// <summary></summary>
        public string OrgField
        {
            get
            {
                return this._OrgField;
            }
            set
            {
                this._OrgField = value;
            }
        }

        private string _CityField;
        /// <summary></summary>
        public string CityField
        {
            get
            {
                return this._CityField;
            }
            set
            {
                this._CityField = value;
            }
        }

        private string _RegionField;
        /// <summary></summary>
        public string RegionField
        {
            get
            {
                return this._RegionField;
            }
            set
            {
                this._RegionField = value;
            }
        }

        private string _PostalCodeField;
        /// <summary></summary>
        public string PostalCodeField
        {
            get
            {
                return this._PostalCodeField;
            }
            set
            {
                this._PostalCodeField = value;
            }
        }

        private string _CountryField;
        /// <summary></summary>
        public string CountryField
        {
            get
            {
                return this._CountryField;
            }
            set
            {
                this._CountryField = value;
            }
        }

        #endregion

        public AddressExtractorInstruction():base(Guid.Empty,Guid.Empty)
        {
            this._DbProvider = DataProviderType.MSSQL;
            this._ConnStr = string.Empty;
            this._SelectSql = string.Empty;
            this._PKField = string.Empty;
            this._FullAddressField = string.Empty;

            this._TgtDbProvider = DataProviderType.MSSQL;
            this._TgtConnStr = string.Empty;
            this._TgtTable = string.Empty;
            this._AddrIDField = string.Empty;
            this._RefKeyField = string.Empty;
            this._StreetField = string.Empty;
            this._SubDivField = string.Empty;
            this._OrgField = string.Empty;
            this._CityField = string.Empty;
            this._RegionField = string.Empty;
            this._PostalCodeField = string.Empty;
            this._CountryField = string.Empty;
        }

        public AddressExtractorInstruction(Guid componentID, Guid jobTicketID,
            DataProviderType dbProvider, string connStr, string selectSql,
            string idField, string addrField,
            DataProviderType tgtDbProvider, string tgtConnStr, string tgtTable, 
            string addrIDField, string refKeyField, 
            string streetField, string subDivField, string comField, 
            string cityField, string regionField, string postalCodeField, 
            string countryField) 
            : base(componentID, jobTicketID)
        {
            this._DbProvider = dbProvider;
            this._ConnStr = connStr;
            this._SelectSql = selectSql;
            this._PKField = idField;
            this._FullAddressField = addrField;

            this._TgtDbProvider = tgtDbProvider;
            this._TgtConnStr = tgtConnStr;
            this._TgtTable = tgtTable;

            this._AddrIDField = addrIDField;
            this._RefKeyField = refKeyField;
            this._StreetField = streetField;
            this._SubDivField = subDivField;
            this._OrgField = comField;
            this._CityField = cityField;
            this._RegionField = regionField;
            this._PostalCodeField = postalCodeField;
            this._CountryField = countryField;
        }

        public override InstructionBase Instantiate(XmlNode xNode)
        {
            if (xNode.Attributes.GetNamedItem("Type").Value == this.GetType().FullName)
            {
                AddressExtractorInstruction instruction = new AddressExtractorInstruction();
                instruction.OwnerComponentID = new Guid(xNode.Attributes.GetNamedItem("ComponentID").Value);
                instruction.OwnerWorkerInstanceID = new Guid(xNode.Attributes.GetNamedItem("WorkerID").Value);
                instruction.SubmitTime = DateTime.Parse(xNode.Attributes.GetNamedItem("SubmitTime").Value);
                instruction.StartTime = DateTime.Parse(xNode.Attributes.GetNamedItem("StartTime").Value);

                instruction.DbProvider = (DataProviderType) int.Parse(
                                                                XmlDataUtil.GetAttributeValue(xNode, "DbProvider",
                                                                                              ((int)
                                                                                               DataProviderType.MSSQL).
                                                                                                  ToString()));
                instruction.ConnStr = XmlDataUtil.GetAttributeValue(xNode, "ConnStr", "");
                instruction.SelectSql = XmlDataUtil.GetAttributeValue(xNode, "SelectSql", "");
                instruction.PKField = XmlDataUtil.GetAttributeValue(xNode, "PKField", "");
                instruction.FullAddressField = XmlDataUtil.GetAttributeValue(xNode, "FullAddressField", "");

                instruction.TgtDbProvider =
                    (DataProviderType)
                    int.Parse(XmlDataUtil.GetAttributeValue(xNode, "TgtDbProvider",
                                                            ((int) DataProviderType.MSSQL).ToString()));
                instruction.TgtConnStr = XmlDataUtil.GetAttributeValue(xNode, "TgtConnStr", "");
                instruction.TgtTable = XmlDataUtil.GetAttributeValue(xNode, "TgtTable", "");
                instruction.AddrIDField = XmlDataUtil.GetAttributeValue(xNode, "AddrIDField", "");
                instruction.RefKeyField = XmlDataUtil.GetAttributeValue(xNode, "RefKeyField", "");
                
                instruction.StreetField = XmlDataUtil.GetAttributeValue(xNode, "StreetField", "");
                instruction.SubDivField = XmlDataUtil.GetAttributeValue(xNode, "SubDivisionField", "");
                instruction.OrgField = XmlDataUtil.GetAttributeValue(xNode, "OrgField", "");
                instruction.CityField = XmlDataUtil.GetAttributeValue(xNode, "CityField", "");
                instruction.RegionField = XmlDataUtil.GetAttributeValue(xNode, "RegionField", "");
                instruction.PostalCodeField = XmlDataUtil.GetAttributeValue(xNode, "PostalCodeField", "");
                instruction.CountryField = XmlDataUtil.GetAttributeValue(xNode, "CountryField", "");
                
                return instruction;
            }
            else
            {
                throw new Exception("Unable to instantiate instruction: invalid type specified in xml node");
            }
        }

        public override XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
        {
            XmlNode xNode = XmlDataUtil.AddElement(ref xDoc, parentNode, "Instruction");
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Type", this.GetType().FullName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ComponentID", this.OwnerComponentID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "WorkerID", this.OwnerWorkerInstanceID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SubmitTime", this.SubmitTime.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "StartTime", this.StartTime.ToString());

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "DbProvider", ((int) this.DbProvider).ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ConnStr", this.ConnStr);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SelectSql", this.SelectSql);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "PKField", this.PKField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FullAddressField", this.FullAddressField);

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TgtDbProvider", ((int) this.TgtDbProvider).ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TgtConnStr", this.TgtConnStr);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TgtTable", this.TgtTable);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "AddrIDField", this.AddrIDField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RefKeyField", this.RefKeyField);

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "StreetField", this.StreetField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SubDivisionField", this.SubDivField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "OrgField", this.OrgField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "CityField", this.CityField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RegionField", this.RegionField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "PostalCodeField", this.PostalCodeField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "CountryField", this.CountryField);
            
            return xNode;
        }
    }
}
